﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MPMovieCatalog.Util
{
    public class Fields
    {
        public static Field Title = new SimpleField("title");
        public static Field Tagline = new SimpleField("tagline");
        public static Field Director = new SimpleField("director");
        public static Field Writer = new SimpleField("writer");
        public static Field Year = new SimpleField("year");
        public static Field Runtime = new SimpleField("runtime");
        public static Field IMDBRating = new SimpleField("imdbRating");
        public static Field IMDBNumber = new SimpleField("imdbNumber");
        public static Field IMDBVotes = new SimpleField("imdbVotes");
        public static Field MPAARating = new SimpleField("mpaaRating");
        public static Field Description = new SimpleField("description");
        public static Field Picture = new SimpleField("picture");
        public static Field Genres = new ListField("genres", "genre");
        public static Field Actors = new ListField("actors", "actor");
        public static Field Files = new ListField("files", "file");

        private static List<Field> m_fields = null;

        public static List<Field> GetFields()
        {
            if (m_fields == null)
            {
                m_fields = new List<Field>();
                m_fields.Add(Title);
                m_fields.Add(Tagline);
                m_fields.Add(Director);
                m_fields.Add(Writer);
                m_fields.Add(Year);
                m_fields.Add(Runtime);
                m_fields.Add(IMDBRating);
                m_fields.Add(IMDBNumber);
                m_fields.Add(IMDBVotes);
                m_fields.Add(MPAARating);
                m_fields.Add(Description);
                m_fields.Add(Picture);
                m_fields.Add(Genres);
                m_fields.Add(Actors);
                m_fields.Add(Files);
            }

            return m_fields;
        }

        public static Field FindFieldByName(string name)
        {
            Field field = null;
            foreach (Field f in GetFields())
            {
                if (f.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                {
                    field = f;
                    break;
                }
            }
            return field;
        }
    }

    public class Field
    {
        protected const string TEMPLATE_HEADER_FORMAT = "<TH class=\"header\"><xsl:value-of select=\"/movies/metadata/field[@name='{0}']/@label\"/></TH>";

        public Field(string name)
        {
            Name = name;
            DisplayName = ResourceUtils.GetSection("template")[name];
            TemplateHeader = string.Format(TEMPLATE_HEADER_FORMAT, name);
        }

        public string Name { get; set; }
        public string DisplayName { get; set; }
        public string TemplateHeader { get; set; }
        public string TemplateValue { get; set; }

        public override string ToString()
        {
            return DisplayName;
        }
    }

    public class SimpleField : Field
    {
        protected const string TEMPLATE_VALUE_FORMAT = "<TD class=\"value\"><xsl:value-of select=\"{0}\"/></TD>";

        public SimpleField(string name)
            : base(name)
        {
            TemplateValue = string.Format(TEMPLATE_VALUE_FORMAT, name);
        }
    }

    public class ListField : Field
    {
        protected const string TEMPLATE_VALUE_FORMAT = "<TD class=\"value\"><xsl:for-each select=\"{0}/{1}\"><xsl:value-of select=\"node()\"/><xsl:if test=\"position()!=last()\"><xsl:text>; </xsl:text></xsl:if></xsl:for-each></TD>";

        public ListField(string name, string singularName)
            : base(name)
        {
            TemplateValue = string.Format(TEMPLATE_VALUE_FORMAT, name, singularName);
        }
    }
}
